﻿#include <iostream>
#include <string>
#include <fstream>
#include <Windows.h>
#include <json/json.h>
using namespace std;

enum Keywords
{
	IF = 0, ELSE, FOR, INt, VOId, MAIN
};
string KeywordsF[] = { "IF", "ELSE", "FOR", "INT", "VOID", "MAIN" };
enum Operators
{
	PLUS = 0, MINUS, MULTI, DIVIDE, PLUSD, MINUSD, MULTID, DIVIDED, LESS, LESSE, GREATER, GREATERE, GIVEVALUE, EQUAL, NEQUAL, NOT
};
string OperatorsF[] = { "PLUS", "MINUS", "MULTI", "DIVIDE", "PLUSD", "MINUSD", "MULTID", "DIVIDED", "LESS", "LESSE", "GREATER", "GREATERE", "GIVEVALUE", "EQUAL", "NEQUAL", "NOT" };
enum Delimiters
{
	BRACEL = 0, BRACER, BRACKETL, BRACKETR, COMMA, SEMICOLON, SQUAREL, SQUARER
};
string DelimitersF[] = { "BRACEL", "BRACER", "BRACKETL", "BRACKETR", "COMMA", "SEMICOLON", "SQUAREL", "SQUARER" };
enum Type
{
	KEYWORD = 0, OPERATOR, CONSt, IDENTIFIER, DELIMITER
};
string TypeF[] = { "KEYWORD", "OPERATOR", "CONST", "IDENTIFIER", "DELIMITER" };

inline bool isDigit(char c)
{
	return (c >= '0' && c <= '9');
}

int tot = 0;

struct Token
{
	Type type;
	int value;
	bool operator == (const Token& a)
	{
		return (type == a.type && value == a.value);
	}
} token[10001];
int tokenNum = 0;
int RH = 1;

string tokensTXT;

void ReadTokens()
{
	ifstream in("_Tokens.txt");
	if (!in.is_open())
	{
		printf("找不到文件！");
		exit(0);
	}
	istreambuf_iterator<char> beg(in), end;
	string source1(beg, end);
	tokensTXT = source1;
}

void DeTXT()
{
	int length = tokensTXT.length();
	for (int i = 0; i < length; )
	{
		string type, value;
		Token temp;
		while (i < length && tokensTXT[i++] != '<');
		while (i < length && tokensTXT[i] != ',') type += tokensTXT[i++];
		i += 2;
		int j;
		for (j = 0; j < 5; j++) if (type == TypeF[j]) break;
		temp.type = Type(j);
		if (temp.type == IDENTIFIER || temp.type == CONSt)
		{
			int t = 0;
			while (i < length && isDigit(tokensTXT[i])) t = t * 10 + tokensTXT[i] - '0', i++;
			temp.value = t;
		}
		else
		{
			while (i < length && tokensTXT[i] != '>') value += tokensTXT[i++];
			if (temp.type == DELIMITER)
			{
				int j;
				for (j = 0; j < 8; j++) if (value == DelimitersF[j]) break;
				temp.value = j;
			}
			if (temp.type == OPERATOR)
			{
				int j;
				for (j = 0; j < 16; j++) if (value == OperatorsF[j]) break;
				temp.value = j;
			}
			if (temp.type == KEYWORD)
			{
				int j;
				for (j = 0; j < 6; j++) if (value == KeywordsF[j]) break;
				temp.value = j;
			}
		}
		token[++tokenNum] = temp;
	}
}

void SetColorAndBackground(int ForgC, int BackC) {
	WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
}
void Print(Token a)
{
	SetColorAndBackground(15, 0);
	Token j = a;
	if (j.type == KEYWORD) cout << "<Keyword, " << KeywordsF[j.value] << ">";
	if (j.type == IDENTIFIER) cout << "<Identifier, " << j.value << ">";
	if (j.type == CONSt) cout << "<Const, " << j.value << ">";
	if (j.type == DELIMITER) cout << "<Delimiter, " << DelimitersF[j.value] << ">";
	if (j.type == OPERATOR) cout << "<Operator, " << OperatorsF[j.value] << ">";
}

void Alert(int rh, Token b)
{
	if (rh <= tokenNum)
	{
		cout << "读取到";
		Print(token[rh]);
	}
	else cout << "程序已结束";
	cout << "，但这里应有一个";
	Print(b);
	cout << endl;
}

Json::Value SENS();
Json::Value SEN(int flag);		//末尾是否需要分号
Json::Value Q();
Json::Value BLOCK();
Json::Value E();
Json::Value E_();
Json::Value T();
Json::Value T_();
Json::Value F();
Json::Value ENTRY();
Json::Value FORR();
Json::Value IFF();
Json::Value DEFF();
Json::Value DE();
Json::Value G();
Json::Value ASSIGNN();
Json::Value CONDITION();


int main()
{
	ReadTokens();
	DeTXT();
	tokenNum--;
	ENTRY();
	printf("语法分析完成，问题已列出，两秒后自动打开语法树网页(仅对编译无问题时产生的结果负责)");
	Sleep(2000);
	system("graph.html");
}

Json::Value SimpleNode(string id)
{
	Json::Value temp;
	temp["id"] = id + "--" + to_string(++tot);
	temp["label"] = id;
	Json::Value style;
	style["fill"] = "#8ce183";
	temp["style"] = style;
	return temp;
}

//递归下降分析所用的函数部分---------------->
Json::Value ENTRY()
{
	Json::Value root;
	root["id"] = "S--" + to_string(++tot);
	root["label"] = "S";
	if (RH <= tokenNum && token[RH] == Token{ KEYWORD, INt }) 
		RH++, root["children"].append(SimpleNode("int")); 
	else Alert(RH, Token{ KEYWORD, INt });
	if (RH <= tokenNum && token[RH] == Token{ KEYWORD, MAIN }) 
		RH++, root["children"].append(SimpleNode("main"));
	else Alert(RH, Token{ KEYWORD, MAIN });
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACKETL })
		RH++, root["children"].append(SimpleNode("("));
	else Alert(RH, Token{ DELIMITER, BRACKETL });
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACKETR }) 
		RH++, root["children"].append(SimpleNode(")"));
	else Alert(RH, Token{ DELIMITER, BRACKETR });
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACEL })
		RH++, root["children"].append(SimpleNode("{"));
	else Alert(RH, Token{ DELIMITER, BRACEL });
	root["children"].append(SENS());
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACER }) 
		RH++, root["children"].append(SimpleNode("}"));
	else Alert(RH, Token{ DELIMITER, BRACER });

	ofstream out;
	out.open("jsonOut.json");
	out << "demo(" << root << ")";
	out.close();
	return root;
}
Json::Value SENS()
{
	Json::Value temp;
	temp["id"] = "SENS--" + to_string(++tot);
	temp["label"] = "SENS";
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACER }) return temp;
	if (RH > tokenNum) return temp;
	temp["children"].append(SEN(1));
	temp["children"].append(Q());
	return temp;
}
Json::Value Q()
{
	Json::Value temp;
	temp["id"] = "Q--" + to_string(++tot);
	temp["label"] = "Q";
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACER }) return temp;
	temp["children"].append(SEN(1));
	temp["children"].append(Q());
	return temp;
}
Json::Value SEN(int flag)
{
	Json::Value temp;
	temp["id"] = "SEN--" + to_string(++tot);
	temp["label"] = "SEN";
	if (RH <= tokenNum && token[RH] == Token{ KEYWORD, FOR }) temp["children"].append(FORR());
	else if (RH <= tokenNum && token[RH] == Token{ KEYWORD, IF }) temp["children"].append(IFF());
	else if (RH <= tokenNum && token[RH].type == IDENTIFIER)
	{
		temp["children"].append(ASSIGNN());
		if (flag)
		{
			if (RH <= tokenNum && token[RH] == Token{ DELIMITER, SEMICOLON })
				RH++, temp["children"].append(SimpleNode(";"));
			else
				printf("%d:缺少分号！\n", RH);
		}
	}
	else if (RH <= tokenNum && token[RH] == Token{ KEYWORD, INt })
	{
		temp["children"].append(DEFF());
		if (flag)
		{
			if (RH <= tokenNum && token[RH] == Token{ DELIMITER, SEMICOLON })
				RH++, temp["children"].append(SimpleNode(";"));
			else
				printf("%d:缺少分号！\n", RH);
		}
	}
	else printf("%d:未预料到的", RH), Print(token[RH]),printf("\n"), RH++;
	return temp;
}
Json::Value BLOCK()
{
	Json::Value temp;
	temp["id"] = "BLOCK--" + to_string(++tot);
	temp["label"] = "BLOCK";
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACEL })
	{
		RH++;
		temp["children"].append(SENS());
		if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACER }) RH++, temp["children"].append(SimpleNode("}")); else Alert(RH, Token{DELIMITER, BRACER});
	}
	else temp["children"].append(SEN(1));
	return temp;
}
Json::Value FORR()
{
	Json::Value temp;
	temp["id"] = "FOR--" + to_string(++tot);
	temp["label"] = "FOR";
	if (RH <= tokenNum && token[RH] == Token{ KEYWORD, FOR })
		RH++, temp["children"].append(SimpleNode("for"));
	else Alert(RH, Token{ KEYWORD, FOR });
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACKETL }) 
		RH++, temp["children"].append(SimpleNode("("));
	else Alert(RH, Token{ DELIMITER, BRACKETL });
	temp["children"].append(SEN(1));
	temp["children"].append(CONDITION());
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, SEMICOLON }) 
		RH++, temp["children"].append(SimpleNode(";"));
	else Alert(RH, Token{ DELIMITER, SEMICOLON });
	temp["children"].append(SEN(0));
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACKETR }) 
		RH++, temp["children"].append(SimpleNode(")"));
	else Alert(RH, Token{ DELIMITER, BRACKETR });
	temp["children"].append(BLOCK());
	return temp;
}
Json::Value IFF()
{
	Json::Value temp;
	temp["id"] = "IF--" + to_string(++tot);
	temp["label"] = "IF";
	if (RH <= tokenNum && token[RH] == Token{ KEYWORD, IF }) 
		RH++, temp["children"].append(SimpleNode("if"));
	else Alert(RH, Token{ KEYWORD, IF });
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACKETL }) 
		RH++, temp["children"].append(SimpleNode("("));
	else Alert(RH, Token{ DELIMITER, BRACKETL });
	temp["children"].append(CONDITION());
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACKETR }) 
		RH++, temp["children"].append(SimpleNode(")"));
	else Alert(RH, Token{ DELIMITER, BRACKETR });
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACEL })
	{
		RH++;
		temp["children"].append(SimpleNode("{"));
		temp["children"].append(SENS());
		if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACER }) 
			RH++, temp["children"].append(SimpleNode("}"));
		else Alert(RH, Token{ DELIMITER, BRACER });
		if (RH <= tokenNum && token[RH] == Token{ KEYWORD, ELSE })
		{
			RH++;
			temp["children"].append(SimpleNode("else"));
			temp["children"].append(BLOCK());
		}
	}
	else
	{
		temp["children"].append(SEN(1));
	}
	return temp;
}
Json::Value ASSIGNN()
{
	Json::Value temp;
	temp["id"] = "ASSIGN--" + to_string(++tot);
	temp["label"] = "ASSIGN";
	if (RH <= tokenNum && token[RH].type == IDENTIFIER) temp["children"].append(SimpleNode("Identifier" + to_string(token[RH].value))), RH++;
	int v = token[RH].value;
	if (RH <= tokenNum && token[RH].type == OPERATOR && (v == GIVEVALUE ||  v == PLUSD || v == MINUSD || v == MULTID || v == DIVIDED))
		temp["children"].append(SimpleNode(OperatorsF[v])),
		RH++;
	else
		printf("%d:此处应有数值运算符，却读取到", RH), Print(token[RH]), printf("\n");
	temp["children"].append(E());
	return temp;
}

Json::Value E()
{
	Json::Value temp;
	temp["id"] = "E--" + to_string(++tot);
	temp["label"] = "E";
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACKETR }) printf("%d:不匹配的括号！\n", RH);
	if (RH <= tokenNum && token[RH].type == OPERATOR) printf("%d:意料之外的运算符！\n", RH);
	if (RH <= tokenNum && token[RH].type == KEYWORD) printf("%d:意料之外的关键字！\n", RH);
	temp["children"].append(T());
	temp["children"].append(E_());
	return temp;
}
Json::Value E_()
{
	Json::Value temp;
	temp["id"] = "E_--" + to_string(++tot);
	temp["label"] = "E'";
	if (RH <= tokenNum && (token[RH] == Token{ OPERATOR, PLUS } || token[RH] == Token{ OPERATOR, MINUS }))
	{
		temp["children"].append(SimpleNode(OperatorsF[token[RH].value]));
		RH++;
		temp["children"].append(T());
		temp["children"].append(E_());
	}
	return temp;
}
Json::Value T()
{
	Json::Value temp;
	temp["id"] = "T--" + to_string(++tot);
	temp["label"] = "T";
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACKETR }) printf("%d:不匹配的括号！\n", RH);
	if (RH <= tokenNum && token[RH].type == OPERATOR) printf("%d:意料之外的运算符！\n", RH);
	if (RH <= tokenNum && token[RH].type == KEYWORD) printf("%d:意料之外的关键字！\n", RH);
	temp["children"].append(F());
	temp["children"].append(T_());
	return temp;
}
Json::Value T_()
{
	Json::Value temp;
	temp["id"] = "T_--" + to_string(++tot);
	temp["label"] = "T'";
	if (RH <= tokenNum && (token[RH] == Token{ OPERATOR, MULTI } || token[RH] == Token{ OPERATOR, DIVIDE }))
	{
		temp["children"].append(SimpleNode(OperatorsF[token[RH].value]));
		RH++;
		temp["children"].append(F());
		temp["children"].append(T_());
	}
	return temp;
}
Json::Value F()
{
	Json::Value temp;
	temp["id"] = "F--" + to_string(++tot);
	temp["label"] = "F";
	if (RH <= tokenNum && token[RH].type == CONSt) temp["children"].append(SimpleNode("Const" + to_string(token[RH].value))), RH++;
	else if (RH <= tokenNum && token[RH].type == IDENTIFIER) temp["children"].append(SimpleNode("Identifier" + to_string(token[RH].value))), RH++;
	else if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACKETL })
	{
		RH++;
		temp["children"].append(SimpleNode("("));
		temp["children"].append(E());
		if (RH <= tokenNum && token[RH] == Token{ DELIMITER, BRACKETR })
			RH++, temp["children"].append(SimpleNode(")"));
		else printf("%d:缺少右括号！\n", RH);
	}
	else printf("%d:本应读取到常数或标识符或左括号\n", RH);
	return temp;
}
Json::Value CONDITION()
{
	Json::Value temp;
	temp["id"] = "CONDITION--" + to_string(++tot);
	temp["label"] = "CONDITION";
	temp["children"].append(E());
	int v = token[RH].value;
	if (RH <= tokenNum && token[RH].type == OPERATOR && (v == LESS || v == LESSE || v == GREATER || v == GREATERE || v == EQUAL || v == NEQUAL))
	{
		temp["children"].append(SimpleNode(OperatorsF[token[RH].value]));
		RH++;
		temp["children"].append(E());
	}
	else printf("%d:此处应有比较运算符，却读取到", RH), Print(token[RH]), printf("\n");
	return temp;
}
Json::Value DEFF()
{
	Json::Value temp;
	temp["id"] = "DEF--" + to_string(++tot);
	temp["label"] = "DEF";
	if (RH <= tokenNum && token[RH] == Token{ KEYWORD, INt }) 
		RH++, temp["children"].append(SimpleNode("int"));
	else Alert(RH, Token{ KEYWORD, INt });
	if (RH <= tokenNum && token[RH].type == IDENTIFIER) 
		temp["children"].append(SimpleNode("Identifier" + to_string(token[RH].value))), RH++;
	else printf("%d:此处本应是标识符\n", RH);
	temp["children"].append(G());
	temp["children"].append(DE());
	return temp;
}
Json::Value G()
{
	Json::Value temp;
	temp["id"] = "G--" + to_string(++tot);
	temp["label"] = "G";
	if (RH <= tokenNum && token[RH] == Token{ OPERATOR, GIVEVALUE })
	{
		temp["children"].append(SimpleNode("="));
		RH++;
		temp["children"].append(E());
	}
	return temp;
}
Json::Value DE()
{
	Json::Value temp;
	temp["id"] = "DE--" + to_string(++tot);
	temp["label"] = "DE";
	if (RH <= tokenNum && token[RH] == Token{ DELIMITER, COMMA })
	{
		RH++;
		temp["children"].append(SimpleNode(","));
		if (RH <= tokenNum && token[RH].type == IDENTIFIER) 
			temp["children"].append(SimpleNode("Identifier" + to_string(token[RH].value))), RH++;
		else printf("%d:此处本应是标识符\n", RH);
		temp["children"].append(G());
		temp["children"].append(DE());
	}
	return temp;
}